package com.clhbolg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.file.FileNameUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clhbolg.domain.Photo;
import com.clhbolg.domain.PhotoAlbum;
import com.clhbolg.domain.bo.PhotoAlbumBo;
import com.clhbolg.domain.vo.PhotoAlbumVo;
import com.clhbolg.enums.FilePathEnum;
import com.clhbolg.mapper.PhotoAlbumMapper;
import com.clhbolg.mapper.PhotoMapper;
import com.clhbolg.model.dto.PageResultDTO;
import com.clhbolg.model.dto.PhotoAlbumAdminDTO;
import com.clhbolg.model.dto.PhotoAlbumDTO;
import com.clhbolg.model.dto.PhotoDTO;
import com.clhbolg.model.vo.request.ConditionVO;
import com.clhbolg.model.vo.request.PhotoAlbumVO;
import com.clhbolg.service.IPhotoAlbumService;
import com.clhbolg.strategy.context.UploadStrategyContext;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 相册Service业务层处理
 *
 * @author cailinhu
 * @date 2023-02-08
 */
@RequiredArgsConstructor
@Service
@DS("slave")
public class PhotoAlbumServiceImpl implements IPhotoAlbumService {

    private final PhotoAlbumMapper baseMapper;


    @Resource
    private PhotoMapper photoMapper;

    @Autowired
    UploadStrategyContext uploadStrategyContext;

    /**
     * 查询相册
     */
    @Override
    public PhotoAlbumVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询相册列表
     */
    @Override
    public TableDataInfo<PhotoAlbumVo> queryPageList(PhotoAlbumBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PhotoAlbum> lqw = buildQueryWrapper(bo);
        Page<PhotoAlbumVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询相册列表
     */
    @Override
    public List<PhotoAlbumVo> queryList(PhotoAlbumBo bo) {
        LambdaQueryWrapper<PhotoAlbum> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PhotoAlbum> buildQueryWrapper(PhotoAlbumBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PhotoAlbum> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getAlbumName()), PhotoAlbum::getAlbumName, bo.getAlbumName());
        lqw.eq(StringUtils.isNotBlank(bo.getAlbumDesc()), PhotoAlbum::getAlbumDesc, bo.getAlbumDesc());
        lqw.eq(StringUtils.isNotBlank(bo.getAlbumCover()), PhotoAlbum::getAlbumCover, bo.getAlbumCover());
        lqw.eq(bo.getIsDelete() != null, PhotoAlbum::getIsDelete, bo.getIsDelete());
        lqw.eq(bo.getStatus() != null, PhotoAlbum::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增相册
     */
    @Override
    public Boolean insertByBo(PhotoAlbumBo bo) {
        PhotoAlbum add = BeanUtil.toBean(bo, PhotoAlbum.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改相册
     */
    @Override
    public Boolean updateByBo(PhotoAlbumBo bo) {
        PhotoAlbum update = BeanUtil.toBean(bo, PhotoAlbum.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PhotoAlbum entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除相册
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<PhotoAlbumDTO> listPhotoAlbums() {
      List<PhotoAlbumDTO>  photoAlbumDTOS= baseMapper.listPhotoAlbumsByNotNull();

//        List<PhotoAlbum> photoAlbumList = baseMapper.selectList(new LambdaQueryWrapper<PhotoAlbum>()
//            .eq(PhotoAlbum::getStatus, PhotoAlbumStatusEnum.PUBLIC.getStatus())
//            .eq(PhotoAlbum::getIsDelete, Boolean.FALSE)
//            .orderByDesc(PhotoAlbum::getId));
        return photoAlbumDTOS;
    }

    @Override
    public PageResultDTO<PhotoAlbumAdminDTO> listPhotoAlbumsAdmin(ConditionVO conditionVO) {

        List<PhotoAlbum> photoAlbums = baseMapper.selectList(Wrappers.lambdaQuery(PhotoAlbum.class)
            .like(StringUtils.isNotBlank(conditionVO.getKeywords()), PhotoAlbum::getAlbumName, conditionVO.getKeywords())
            .eq(PhotoAlbum::getIsDelete, false));
        /**
         * 循环查库的方式
         *
         * 为什么不用sql，因为我想偷懒
         * sql：
         *      select t_photo_album.* ,count(tp.album_id)from t_photo_album
         *      left join t_photo tp on t_photo_album.id = tp.album_id
         *      where  t_photo_album.album_name like concat('%','','%')
         *      group by t_photo_album.id
         *
         */
        List<PhotoAlbumAdminDTO> collect = photoAlbums.stream().map(e -> {
            PhotoAlbumAdminDTO photoAlbumAdminDTO = BeanUtil.copyProperties(e, PhotoAlbumAdminDTO.class);
            photoAlbumAdminDTO.setPhotoCount(Convert.toInt(
                photoMapper.selectCount(
                    Wrappers.lambdaQuery(Photo.class).eq(Photo::getAlbumId, e.getId()).eq(Photo::getIsDelete,false)))
            );
            return photoAlbumAdminDTO;
        }).collect(Collectors.toList());

        return new PageResultDTO<>(collect,photoAlbums.size());
    }

    @Override
    public void saveOrUpdatePhotoAlbum(PhotoAlbumVO photoAlbumVO) {
        //判断名字是否重复
        String albumName = photoAlbumVO.getAlbumName();
        LambdaQueryWrapper<PhotoAlbum> wrapper = Wrappers.lambdaQuery(PhotoAlbum.class).eq(PhotoAlbum::getAlbumName, albumName);
        Long count = baseMapper.selectCount(wrapper);
        if (count>0) throw new GlobalException(String.format("【%s】已经存在!",albumName));
        PhotoAlbum photoAlbum = BeanUtil.copyProperties(photoAlbumVO, PhotoAlbum.class);
        baseMapper.insertOrUpdate(photoAlbum);
    }

    @Override
    public PhotoAlbumAdminDTO getInfo(Integer albumId) {
        PhotoAlbum photoAlbum = baseMapper.selectById(albumId);
        PhotoAlbumAdminDTO photoAlbumAdminDTO = BeanUtil.copyProperties(photoAlbum, PhotoAlbumAdminDTO.class);
        photoAlbumAdminDTO.setPhotoCount(Convert.toInt(
            photoMapper.selectCount(
                Wrappers.lambdaQuery(Photo.class).eq(Photo::getAlbumId, albumId))));
        return photoAlbumAdminDTO;
    }

    @Override
    public List<PhotoAlbumDTO> listPhotoAlbumInfosAdmin() {
        List<PhotoAlbum> photoAlbums = baseMapper.selectList(new LambdaQueryWrapper<PhotoAlbum>()
            .eq(PhotoAlbum::getIsDelete, false));
        return BeanUtil.copyToList(photoAlbums, PhotoAlbumDTO.class);
    }

    @Override
    @Transactional
    public void deleteAlbums(Long id) {
        //查询出所有的相册进行逻辑删除
        Long count = photoMapper.selectCount(Wrappers.lambdaQuery(Photo.class).eq(Photo::getAlbumId, id));
        if (count>0){
            //逻辑删除相册
            baseMapper.updateById(PhotoAlbum.builder().id(id).isDelete(1).build());
            //逻辑删除相片
            photoMapper.update(new Photo(),Wrappers.lambdaUpdate(Photo.class).set(Photo::getIsDelete,1).eq(Photo::getAlbumId,id));
        }else {
            //直接删除需要删除阿里云
            String albumCover = baseMapper.selectById(id).getAlbumCover();
            String name = FileNameUtil.getName(albumCover);
            //如果是个空相册，直接删除
            baseMapper.deleteById(id);
            uploadStrategyContext.executeDeleteStrategy(FilePathEnum.PHOTO.getPath()+name);
        }

    }

    @Override
    public PhotoDTO selectPhotoByAlbum(Integer albumId,ConditionVO condition) {
        PhotoAlbum photoAlbum = baseMapper.selectById(albumId);
        Page<Photo> photoPage = photoMapper.
            selectPage(condition.build(), Wrappers.lambdaQuery(Photo.class).select(Photo::getPhotoSrc).eq(Photo::getAlbumId, albumId));
        List<String> list = photoPage.getRecords().stream().map(Photo::getPhotoSrc).collect(Collectors.toList());
        PhotoDTO build = PhotoDTO.builder().photoAlbumName(photoAlbum.getAlbumName()).photoAlbumCover(photoAlbum.getAlbumCover()).photos(list).build();
        return build;
    }
}
